﻿using System;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using StackExchange.Redis;

namespace PubSub.S1
{
    public class Level1
    {
        private class RedisHelper
        {
            public static ConnectionMultiplexer ConnectionRedis(EndPoint endPoint, string password)
            {
                var configurationOptions = new ConfigurationOptions
                {
                    EndPoints =
                    {
                        endPoint
                        //{"127.0.0.1",6379}
                    },
                    //注释ServiceName，非哨兵模式会报错，哨兵模式已经废弃，目前只支持单节点和集群模式
                    //ServiceName = endPoint.ToString(),
                    AllowAdmin = true,
                    //Password = password,
                    SyncTimeout = (int) TimeSpan.FromSeconds(value: 60).TotalMilliseconds,
                };
                if (!string.IsNullOrWhiteSpace(password))
                {
                    configurationOptions.Password = password;
                }

                var connectionMultiplexer = ConnectionMultiplexer.Connect(configurationOptions);
                connectionMultiplexer.PreserveAsyncOrder = false;
                connectionMultiplexer.ConnectionRestored += ConnectionMultiplexerOnConnectionRestored;
                connectionMultiplexer.ConnectionFailed += ConnectionMultiplexerOnConnectionFailed;
                return connectionMultiplexer;
            }

            private static void ConnectionMultiplexerOnConnectionRestored(object sender,
                ConnectionFailedEventArgs connectionFailedEventArgs)
            {
            }

            private static void ConnectionMultiplexerOnConnectionFailed(object sender,
                ConnectionFailedEventArgs connectionFailedEventArgs)
            {
            }
        }

        public static void Test()
        {
            Console.WriteLine("方案一：最简方案!");
            Task.Run(() => { Publish(); });
            Task.Run(() => { Subscribe("c1"); });
            Task.Run(() => { Subscribe("c2"); });
            Task.Run(() => { Subscribe("c3"); });
            Task.Run(() => { Subscribe("c4"); });
            Task.Run(() => { Subscribe("c5"); });
            Task.Run(() => { Subscribe("c6"); });
            
            Console.ReadLine();
        }

        static void Subscribe(string clientName)
        {
            var redis = RedisHelper.ConnectionRedis(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6379), string.Empty);
            var sub = redis.GetSubscriber();
            sub.Subscribe("ch",
                (channel, message) =>
                {
                    Console.WriteLine($"client:{clientName}\tchannel:{channel},\tmessage:{message}");
                });
        }

        static void Publish()
        {
            try
            {
                var redis = RedisHelper.ConnectionRedis(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6379), "");
                var sub = redis.GetSubscriber();
                while (true)
                {
                    Thread.Sleep(100);
                    var channel = new RedisChannel("ch", RedisChannel.PatternMode.Auto);
                    sub.Publish(channel, new RedisValue(DateTime.Now.ToShortTimeString()));
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
    }
}